package mediasManagement;

import hibernateUtils.HibernateUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.Session;
import org.hibernate.annotations.Cascade;

import exceptions.LentBookException;
import exceptions.LentMediaException;

import loansManagement.Loan;
import loansManagement.Reservation;

@Entity
public class Exemplary {

	/**
	 * @uml.property  name="exemplaryId"
	 */
	@Id
	@Column(name="EXEMPLARY_ID",unique = true,nullable=true)
	private String exemplaryId;

	/**
	 * Getter of the property <tt>exemplaryId</tt>
	 * @return  Returns the exemplaryId.
	 * @uml.property  name="exemplaryId"
	 */
	public String getExemplaryId() {
		return exemplaryId;
	}

	/**
	 * Setter of the property <tt>exemplaryId</tt>
	 * @param exemplaryId  The exemplaryId to set.
	 * @uml.property  name="exemplaryId"
	 */
	public void setExemplaryId(String exemplaryId) {
		this.exemplaryId = exemplaryId;
	}

		
		/**
		 */
	public Exemplary(Media media){
			this.media=media;
			this.exemplaryId=media.getMediaNumberId()+"_"+media.getCreatedExemplariesNumber();
			
		}
	public Exemplary(String exemplaryId,Media media){
			this.media=media;
			this.exemplaryId=exemplaryId+"_"+media.getCreatedExemplariesNumber();
		}
	public Exemplary(){
		
	}
		
	@Override
	public boolean equals(Object exemplary) {
		if ( exemplary == null)
			return false;
		
		Exemplary ex = (Exemplary) exemplary;
		if(ex.getExemplaryId().equals(exemplaryId))
			return true		

;
		
		return false;
		}


	public boolean isLent() {
		return ((currentLoan !=null)&&(!currentLoan.isIsReturn()));
		
	}


	public void lend(Loan loan) throws LentMediaException {
		//if (this.isLent())
			//throw new LentMediaException("Media already lent.");

		this.currentLoan=loan;
		//t  his.loans.add(loan);
		//Session session= HibernateUtil.openSession();
		//session.merge(this);
	}

	public void returnMedia() {
	}

	/**
	 * @uml.property  name="media"
	 * @uml.associationEnd  inverse="exemplaries:mediasManagement.Media"
	 */
	@ManyToOne
    @JoinColumn(name="media_fk")
	private Media media;

	/**
	 * Getter of the property <tt>media</tt>
	 * @return  Returns the media.
	 * @uml.property  name="media"
	 */
	public Media getMedia() {
		return media;
	}

	/**
	 * Setter of the property <tt>media</tt>
	 * @param media  The media to set.
	 * @uml.property  name="media"
	 */
	public void setMedia(Media media) {
		this.media = media;
	}

	/**
	 * @uml.property   name="currentLoan"
	 * @uml.associationEnd   inverse="exemplary:loansManagement.Loan"
	 */
	
	@OneToOne( mappedBy = "pk.exemplary",cascade=CascadeType.ALL,fetch=FetchType.EAGER )
	 //@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE 
		//   /* org.hibernate.annotations.CascadeType.DELETE_ORPHAN*/})
	private Loan currentLoan;

	/**
	 * Getter of the property <tt>currentLoan</tt>
	 * @return  Returns the currentLoan.
	 * @uml.property  name="currentLoan"
	 */
	
	public Loan getCurrentLoan() {
		return currentLoan;
	}

	/**
	 * Setter of the property <tt>currentLoan</tt>
	 * @param currentLoan  The currentLoan to set.
	 * @uml.property  name="currentLoan"
	 */
	public void setCurrentLoan(Loan currentLoan) {
		this.currentLoan = currentLoan;
	}

	@Override
	public String toString(){
		return "the exemplary "+exemplaryId+" of "+media.getTitle();
		
		
		
	}

	/**
	 * @uml.property  name="reserved"
	 */
	private boolean reserved=false;

	/**
	 * Getter of the property <tt>reserved</tt>
	 * @return  Returns the reserved.
	 * @uml.property  name="reserved"
	 */
	public boolean isReserved() {
		return reserved;
	}

	/**
	 * Setter of the property <tt>reserved</tt>
	 * @param reserved  The reserved to set.
	 * @uml.property  name="reserved"
	 */
	public void setReserved(boolean reserved) {
		this.reserved = reserved;
	}

	/** 
	 * @uml.property name="reservation"
	 * @uml.associationEnd inverse="exemplary:loansManagement.Reservation"
	 */
	// @OneToOne(cascade = CascadeType.ALL)
//	 //@PrimaryKeyJoinColumn
//	private Reservation reservation;
//
//	/** 
//	 * Getter of the property <tt>reservation</tt>
//	 * @return  Returns the reservation.
//	 * @uml.property  name="reservation"
//	 */
//	public Reservation getReservation() {
//		return reservation;
//	}
//
//	/** 
//	 * Setter of the property <tt>reservation</tt>
//	 * @param reservation  The reservation to set.
//	 * @uml.property  name="reservation"
//	 */
//	public void setReservation(Reservation reservation) {
//		this.reservation = reservation;
//	}
//		

}
